<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>广播</title>
    <style>
        button {
            font-size: 28px
        }

        .stage {
            height: 500px;
            width: 800px;
            background-color: #000;
            position: relative;
        }

        .danmu {
            color: #FFF;
            position: absolute;
            top: 240px;
            font-size: 24px;
            width: 500px;
            overflow: hidden;
            height: 40px;
            /* position: relative; */
        }

        .danmu-content {
            position: absolute;
            /*  不换行 */
            /* width: 100%; */
            white-space: nowrap;
            text-align: center;
            display: inline-block;
            min-width: 500px;
        }
    </style>
</head>

<body>

    <div>
        <button type="button" onclick="broadcast(1)">长消息广播</button>
        <button type="button" onclick="broadcast(0)">短消息广播</button>
    </div>
    <div>
        <div class="stage">

        </div>
    </div>

    <script>

        const DANMU_WIDTH = 500;
        const stageWidth = 800;
        const shortMessage = "短消息";
        const longMessage = "我是长消息我是长消息我是长消息我是长消息我是长消息我是长消息我是长消息我是长消息我是长消息我是长消息";

        const stageEl = document.querySelector('.stage');
        let danmuEl;

        // 创建消息节点并播报
        function broadcast(type) {
            danmuEl = createDanmuEl(type ? longMessage : shortMessage);
            stageEl.appendChild(danmuEl);
            startAnimate();
        }

        // 创建消息节点
        function createDanmuEl(message) {
            const el = document.createElement("div");
            el.className = "danmu";

            const contentWrapper = document.createElement("div");
            contentWrapper.className = "danmu-content-wrapper"

            const contentEl = document.createElement("div");
            contentEl.className = "danmu-content"
            contentEl.textContent = message;

            contentWrapper.appendChild(contentEl)

            el.appendChild(contentWrapper);
            return el;
        }

        async function startAnimate() {
            // 滑入
            const totalWidth = stageWidth + DANMU_WIDTH;
            const centerX = stageWidth * 0.5 - DANMU_WIDTH * 0.5;

            // 计算偏移量
            const kfsIn = {
                transform: [`translateX(${totalWidth}px)`, `translateX(${centerX}px)`]
            }
            await danmuEl.animate(kfsIn, {
                duration: 2000,
                fill: 'forwards',
                easing: 'ease-out'
            }).finished;

            // 暂停部分
            const contentEl = danmuEl.querySelector(".danmu-content");
            // 获取消息元素的长度
            const itemWidth = contentEl.getBoundingClientRect().width;
            // 计算需要滚动的长度
            const gapWidth = Math.max(0, itemWidth - DANMU_WIDTH);
            // 计算需要滚动的时间
            const duration = Math.max(0, Math.floor(gapWidth / 200) * 1000);
            const translateX = duration > 0 ? gapWidth : 0;
            // 偏移量
            const kfsTxt = {
                transform: [`translateX(0px)`, `translateX(-${gapWidth}px)`]
            };
            await contentEl.animate(kfsTxt, {
                duration,
                delay: 2000,
                fill: 'forwards',
                easing: 'linear',
            }).finished;
            // 滑出
            const kfsOut = {
                transform: [`translateX(${centerX}px)`, `translateX(-${DANMU_WIDTH}px)`]
            };
            await danmuEl.animate(kfsOut, {
                duration: 2000,
                fill: "forwards",
                easing: 'ease-in'
            }).finished;

            if (danmuEl) {
                stageEl.removeChild(danmuEl);
            }
            isAnimating = false
        }
    </script>
</body>

</html>